package purchasePlan

import (
	"context"
	"errors"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
	"insighttracking/apps/purchase/auth"
	"insighttracking/common/utils"
	"insighttracking/query/dao"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"net/http"

	"insighttracking/apps/purchase/internal/svc"
	"insighttracking/apps/purchase/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type CreatePurchasePlanBySpuApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewCreatePurchasePlanBySpuApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *CreatePurchasePlanBySpuApiLogic {
	hostname, _ := os.Hostname()
	return &CreatePurchasePlanBySpuApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *CreatePurchasePlanBySpuApiLogic) CreatePurchasePlanBySpuApi(req *types.CreatePurchasePlanBySpuReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}
	spuIdList := k.Map(req.SpuList, func(item types.CreatePurchasePlanSpuReq, index int) int64 {
		return item.SpuID
	})
	spuEntities, err := dao.SpuEntity.WithContext(l.ctx).Where(dao.SpuEntity.ID.In(spuIdList...)).Find()
	if err != nil || len(spuEntities) == 0 {
		return "", errors.New("创建失败")
	}
	unitIdList := k.Map(spuEntities, func(item *model.SpuEntity, index int) int64 {
		return item.UnitID
	})
	unitEntities, err := dao.UnitEntity.WithContext(l.ctx).Where(dao.UnitEntity.ID.In(unitIdList...)).Find()
	var unitNameMap = make(map[int64]string)
	if err == nil && len(unitEntities) > 0 {
		unitNameMap = k.ToMap(unitEntities, func(item *model.UnitEntity) (int64, string) {
			return item.ID, item.Name
		})
	}
	spuMap := k.ToMap(spuEntities, func(item *model.SpuEntity) (int64, *model.SpuEntity) {
		return item.ID, item
	})
	tx := dao.Use(l.svcCtx.MysqlDb).Begin()
	// 生成采购计划单
	for _, item := range req.SpuList {
		currentSpu, isOk := spuMap[item.SpuID]
		if !isOk {
			continue
		}
		requirementsCount, _ := decimal.NewFromString(item.RequirementsCount)
		purchaserPrice, _ := decimal.NewFromString(item.PurchaserPrice)
		purchasePlanEntity, err := service.PurchasePlanService.GetPurchasePlanApi(l.ctx, accountInfo.EnterpriseId, item.SpuID, item.SupplierID, item.PurchaserID, utils.DateTimeStrToTime(item.ExpectationGoodsDate))
		if errors.Is(err, gorm.ErrRecordNotFound) {
			purchasePlanData := model.PurchasePlanEntity{
				OrderNo:                 utils.GenerateTodayOrderNo(l.svcCtx.RedisDb, "CG"), // 操作流水号
				EnterpriseID:            accountInfo.EnterpriseId,                           // 关联到enterprise表主键id
				PurchaserID:             item.PurchaserID,                                   // 采购员,关联到
				SupplierID:              item.SupplierID,                                    // 供应商
				DefaultSupplierID:       item.SupplierID,                                    // 默认供应商
				SpuID:                   item.SpuID,                                         // 商品,关联到spu表主键id
				SnapshotSpuName:         currentSpu.Name,                                    // '快照商品名称
				SnapshotProductImageURL: currentSpu.ProductImageURL,                         // 快照产品图片
				SnapshotSpuType:         currentSpu.SpuType,                                 // 快照商品类型,0表示基础商品,1表示加工商品
				SnapshotUnit:            unitNameMap[currentSpu.UnitID],                     // 快照单位
				SnapshotCategory:        currentSpu.CategoryName,                            // 快照分类
				SnapshotCategoryID:      currentSpu.CategoryID,                              // 快照分类
				LossRate:                currentSpu.LossRate,                                // 损耗率                                  // 快照损耗率
				ExpectationGoodsDate:    utils.DateTimeStrToTime(item.ExpectationGoodsDate), // 期望收货日期
				RequirementsCount:       requirementsCount,                                  // 需求数量
				SnapshotPrice:           purchaserPrice,                                     // 快照商品单价
				Source:                  2,                                                  // 来源,0表示pc端手动点击订单,1表示定时任务,2表示手机端创建,3pc端手动创建
				Types:                   req.Types,                                          // 类型,0表示供应商,1表示现场采购
				Remark:                  req.Remark,                                         // 备注
			}
			if err = service.PurchasePlanService.CreateApi(l.ctx, tx, &purchasePlanData); err != nil {
				if err = tx.Rollback(); err != nil {
					return "", err
				}
				return "", errors.New("创建失败")
			}
		} else {
			// 更新数据
			requirementsCount1 := purchasePlanEntity.RequirementsCount.Add(requirementsCount)
			if err = service.PurchasePlanService.ModifyRequirementsCountByIdApi(l.ctx, tx, purchasePlanEntity.ID, requirementsCount1); err != nil {
				if err = tx.Rollback(); err != nil {
					return "", err
				}
				return "", errors.New("创建失败")
			}
		}
	}

	if err = tx.Commit(); err != nil {
		return "", errors.New("创建失败")
	}
	return "操作成功", nil
}
